﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace InDepth2Demo.Chapter12
{
    public class BranchQuery<T> : IQueryable<T>
    {
        // 声明简单的自动属性
        public Expression Expression { get; private set; }

        public Type ElementType { get; private set; }

        public IQueryProvider Provider { get; private set; }

        public BranchQuery(IQueryProvider provider, Expression expression)
        {
            Expression = expression;
            Provider = provider;
            ElementType = typeof(T);
        }

        public BranchQuery() : this(new BranchQueryProvider(), null)
        {
            Expression = Expression.Constant(this);         // 使用这个查询作为初始表达式
        }

        public IEnumerator<T> GetEnumerator()
        {
            //Logger.Log(this, Expression);
            return Enumerable.Empty<T>().GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()         // 返回空结果序列
        {
            return Enumerable.Empty<T>().GetEnumerator();
        }

        public override string ToString()
        {
            return "BranchQuery";                   // 为了进行日志记录而进行覆盖
        }
    }

    internal class BranchQueryProvider : IQueryProvider
    {
        public IQueryable CreateQuery(Expression expression)
        {
            Type queryType = typeof(BranchQuery<>).MakeGenericType(expression.Type);
            object[] constructorArgs = new object[] { this, expression };
            return (IQueryable)Activator.CreateInstance(queryType, constructorArgs);
        }
        public IQueryable<T> CreateQuery<T>(Expression expression)
        {
            return new BranchQuery<T>(this, expression);
        }
        public object Execute(Expression expression)
        {
            return null;
        }

        public T Execute<T>(Expression expression)
        {
            return default(T);
        }
    }

    public class BranchQueryDemo
    {
        //代码 显示了一个简单查询表达式，用于（假设要）在我们的模拟数据源中查找以“abc”开头的所有字符串，
        //并把结果投影到包含匹配字符串的长度数值的序列中。我们遍历这个结果，不过不用它们做任何事情，这是因为已经知道它们是空的。
        //当然，我们没有源数据，并且也没有编写任何代码来执行真正的过滤——我们只是记录在创建查询表达式并遍历结果的过程中，LINQ所进行的调用。
        public static void Call()
        {
            var query = from x in new BranchQuery<string>()
                        where x.StartsWith("abc")
                        select x.Length;
            foreach (var x in query) { }

        }
    }
}
